<template>
  <div class="yh_slider" >
    <div 
      class="yh_slider_runway" 
      ref="yh_slider_runway" 
    >
      <div class="yh_background" >
        <slot name="background"/>
      </div>
      <div 
        class="yh_slider_bar" 
        ref="yh_slider_bar" 
        :style="{width:sliderBarW+'px', transition: pointerDown ? 'none' : '.5s width'}"
      >
        <div class="yh_sliderRun" >
          <slot name="run"/>
        </div>
        <div class="yh_slider_button-wrapper" ref="yh_slider_button-wrapper">
          <div 
            :class="['yh_slider_button',(disabled || (value && !pointerDown))? 'yh_slider_button_disabled' : '',value?'yh_slider_green':'']" 
            @pointerdown="onButtonDown"  
            :style="{width:'100%',height:'100%',}"
          >
            <div class="yh_sliderBtncont" >
              <slot name="button"/>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
  export default {
    name: 'yh_sliderbtn',
    data(){
      return {
        sliderButDom:null,//整个按下的按钮
        sliderRunwayDom:null,
        sliderBarDom:null,//已经拖过的进度，蓝色部分
        sliderBarW:60,
        buttonWrapLeft:0,
        originLeft:0,
        originX:0,
        pointerDown:false,
      }
    },
    props:{
      disabled:{
        type:Boolean,
        default:false,
      },
      change:{
        type:Event,
        default:()=>{}
      },
      changeStop:{
        type:Event,
        default:()=>{}
      },
      value:{
        type:Boolean,
        default:false,
      }
    },
    model:{
      prop:'value',
      event:'changeValue'
    },
    mounted(){
      this.sliderButDom = this.$refs['yh_slider_button-wrapper'];
      this.sliderRunwayDom = this.$refs['yh_slider_runway'];
      this.sliderBarDom = this.$refs['yh_slider_bar'];

      this.initsliderBarW();
    },
    watch:{
      value:{
        handler(){
          !this.pointerDown && this.initsliderBarW();//按下抬起前，v-model值改变，不影响当前进度条
        },
        immediate:true,
      }
    },
    methods: {
      initsliderBarW(){
        if(!this.sliderRunwayDom || !this.sliderButDom){
          return;
        }
        var sliderBarW = this.value ? this.sliderRunwayDom.offsetWidth : this.sliderButDom.offsetWidth;

        this.sliderBarW = Math.min(sliderBarW,this.sliderRunwayDom.offsetWidth);
      },
      onButtonDown(event){
        if(this.disabled || this.value){
          return;
        }
        event.preventDefault(event);

        this.pointerDown = true;
        this.pointerDownFn(event);
        window.addEventListener('pointermove', this.pointerMoveFn);
        window.addEventListener('pointerup', this.pointerUpFn);
        window.addEventListener('contextmenu', this.pointerUpFn);
      },
      pointerUpFn(){
        window.removeEventListener('pointermove', this.pointerMoveFn);
        window.removeEventListener('pointerup', this.pointerUpFn);
        
        this.pointerDown = false;
        var num = (this.sliderBarDom.offsetWidth - this.sliderButDom.offsetWidth)/(this.sliderRunwayDom.offsetWidth - this.sliderButDom.offsetWidth);
        if(num!==1){//弹回
          this.initsliderBarW();
        }else{
          this.$emit('changeValue',true);

        }
        this.$emit('changeStop',Math.floor(num*100)===100);
      },
      pointerDownFn(event){
        this.originX = event.clientX;
        this.originLeft = this.sliderButDom.offsetLeft;
      },
      pointerMoveFn(event){
        var width = (event.clientX - this.originX) + this.originLeft;

        //拖动条宽度计算
        var sliderBarW = Math.max(this.sliderButDom.offsetWidth,width+this.sliderButDom.offsetWidth);
        sliderBarW = Math.min(sliderBarW,this.sliderRunwayDom.offsetWidth);
        this.sliderBarW = sliderBarW;

        var num = (this.sliderBarDom.offsetWidth - this.sliderButDom.offsetWidth)/(this.sliderRunwayDom.offsetWidth - this.sliderButDom.offsetWidth);
        this.$emit('change',Math.floor(num*100));
        if(num===1){
          this.$emit('changeValue',true);
        }else{
          this.$emit('changeValue',false);
        }
      }
    },
  };
</script>
<style scoped>
.yh_slider{
  width:200px;
  height:40px;
  border-radius:999999px;
}
.yh_slider_runway{
  position:relative;
  width:100%;
  height:100%;
  background-color:#e4e7ed;
  border-radius:999999px;
}
.yh_background{
  position:absolute;
  width:100%;
  height:100%;
  border-radius:999999px;
}
.yh_slider_bar{
  position:relative;
  width:60px;
  background-color:#409eff;
  height:100%;
  border-radius:999999px;
}
.yh_slider_bar_disabled{
  background-color:#c0c4cc;
}
.yh_slider_button-wrapper{
  position:absolute;
  top:0;
  right:0;
  width:60px;
  height:100%;
  user-select: none;
  border-radius:999999px;
}
.yh_slider_button{
  width:120%;
  height:100%;
  background-color:red;
  cursor: pointer;
  text-align:center;
  border-radius:999999px;
}
.yh_slider_green{
  background-color:#13ce66;
}
.yh_slider_button_disabled{
  cursor:  no-drop;
}
.yh_sliderRun{
  width:100%;
  height:100%;
}
.yh_sliderBtncont{
  width:100%;
  height:100%;
}
</style>
